﻿using System;
using System.Collections.Generic;
using System.Linq;
using Amazon.SimpleNotificationService;
using Amazon.SimpleNotificationService.Model;
using NUnit.Framework;
using Rhino.Mocks;
using ShuttleBus.Transports.AmazonSqs.Clients;


namespace Tests.Transports.AmazonSqs.SnsWrapperTests
{
    public partial class SnsWrapperTests
    {
        [TestFixture]
        public class WhenQueryingSubscriptions
        {
            private AmazonSimpleNotificationService _sns;
            private SnsWrapper _wrapper;

            [SetUp]
            public void SetUp()
            {
                _sns = MockRepository.GenerateMock<AmazonSimpleNotificationService>();
                _wrapper = new SnsWrapper(_sns);
            }

            [TearDown]
            public void TearDown()
            {
                _sns.VerifyAllExpectations();
            }

            [Test]
            public void No_Subscriptions_Exist()
            {
                var response = new ListSubscriptionsResponse
                                   {
                                       ListSubscriptionsResult = new ListSubscriptionsResult { Subscriptions = new List<Subscription>() }
                                   };

                _sns.Expect(s => s.ListSubscriptions(Arg<ListSubscriptionsRequest>.Is.NotNull)).Return(response);
                var results = _wrapper.QuerySubscriptions("some name");

                Assert.AreEqual(0, results.Count());
            }

            [Test]
            public void No_Subscriptions_Exist_Matching_This_Name()
            {
                var response = new ListSubscriptionsResponse
                {
                    ListSubscriptionsResult = new ListSubscriptionsResult
                    {
                        Subscriptions = new List<Subscription>
                                            {
                                                new Subscription
                                                    {
                                                        Endpoint = "arn:aws:sqs:us-east-1:123456789012:some-endpoint",
                                                        Owner = "123456789012",
                                                        Protocol = "sqs",
                                                        SubscriptionArn = "arn:aws:sns:us-east-1:123456789012:some-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99",
                                                        TopicArn = "arn:aws:sns:us-east-1:162882392992:some-message"
                                                    }
                                            }
                    }
                };
                _sns.Expect(s => s.ListSubscriptions(Arg<ListSubscriptionsRequest>.Is.NotNull)).Return(response);
                var results = _wrapper.QuerySubscriptions("mymessage");

                Assert.AreEqual(0, results.Count());
            }

            [Test]
            public void No_Sqs_Subscriptions_Exist_For_This_Message_Type()
            {
                var response = new ListSubscriptionsResponse
                {
                    ListSubscriptionsResult = new ListSubscriptionsResult
                    {
                        Subscriptions = new List<Subscription>
                                            {
                                                new Subscription
                                                    {
                                                        Endpoint = "arn:aws:sqs:us-east-1:123456789012:some-endpoint",
                                                        Owner = "123456789012",
                                                        Protocol = "sqs",
                                                        SubscriptionArn = "arn:aws:sns:us-east-1:123456789012:some-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99",
                                                        TopicArn = "arn:aws:sns:us-east-1:162882392992:some-message"
                                                    },
                                                     new Subscription
                                                    {
                                                        Endpoint = "arn:aws:sqs:us-east-1:123456789012:some-endpoint",
                                                        Owner = "123456789012",
                                                        Protocol = "email",
                                                        SubscriptionArn = "arn:aws:sns:us-east-1:123456789012:some-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99",
                                                        TopicArn = "arn:aws:sns:us-east-1:162882392992:mymessage"
                                                    }
                                            }
                    }
                };
                _sns.Expect(s => s.ListSubscriptions(Arg<ListSubscriptionsRequest>.Is.Anything)).Return(response);
                var results = _wrapper.QuerySubscriptions("mymessage");

                Assert.AreEqual(0, results.Count());
            }

            [Test]
            public void Single_Subscription_Exists_Matching_This_Name()
            {
                var response = new ListSubscriptionsResponse
                {
                    ListSubscriptionsResult = new ListSubscriptionsResult
                    {
                        Subscriptions = new List<Subscription>
                                            {
                                                new Subscription
                                                    {
                                                        Endpoint = "arn:aws:sqs:us-east-1:123456789012:some-endpoint",
                                                        Owner = "123456789012",
                                                        Protocol = "sqs",
                                                        SubscriptionArn = "arn:aws:sns:us-east-1:123456789012:some-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99",
                                                        TopicArn = "arn:aws:sns:us-east-1:162882392992:some-message"
                                                    },
                                                     new Subscription
                                                    {
                                                        Endpoint = "arn:aws:sqs:us-east-1:123456789012:some-endpoint",
                                                        Owner = "123456789012",
                                                        Protocol = "sqs",
                                                        SubscriptionArn = "arn:aws:sns:us-east-1:123456789012:some-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99",
                                                        TopicArn = "arn:aws:sns:us-east-1:162882392992:mymessage"
                                                    }
                                            }
                    }
                };
                _sns.Expect(s => s.ListSubscriptions(Arg<ListSubscriptionsRequest>.Is.Anything)).Return(response);
                var results = _wrapper.QuerySubscriptions("mymessage").ToArray();

                Assert.AreEqual(1, results.Count());
                Assert.AreEqual("arn:aws:sqs:us-east-1:123456789012:some-endpoint", results[0].Endpoint);
                Assert.AreEqual("123456789012", results[0].Owner);
                Assert.AreEqual("sqs", results[0].Protocol);
                Assert.AreEqual("arn:aws:sns:us-east-1:123456789012:some-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99", results[0].SubscriptionArn);
                Assert.AreEqual("arn:aws:sns:us-east-1:162882392992:mymessage", results[0].TopicArn);
            }

            [Test]
            public void Multiple_Subscriptions_Exists_Matching_This_Name()
            {
                var response = new ListSubscriptionsResponse
                {
                    ListSubscriptionsResult = new ListSubscriptionsResult
                    {
                        Subscriptions = new List<Subscription>
                                            {
                                                new Subscription
                                                    {
                                                        Endpoint = "arn:aws:sqs:us-east-1:123456789012:some-endpoint",
                                                        Owner = "123456789012",
                                                        Protocol = "sqs",
                                                        SubscriptionArn = "arn:aws:sns:us-east-1:123456789012:some-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99",
                                                        TopicArn = "arn:aws:sns:us-east-1:162882392992:some-message"
                                                    },
                                                     new Subscription
                                                    {
                                                        Endpoint = "arn:aws:sqs:us-east-1:123456789012:some-endpoint",
                                                        Owner = "123456789012",
                                                        Protocol = "sqs",
                                                        SubscriptionArn = "arn:aws:sns:us-east-1:123456789012:some-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99",
                                                        TopicArn = "arn:aws:sns:us-east-1:162882392992:mymessage"
                                                    },
                                                     new Subscription
                                                    {
                                                        Endpoint = "arn:aws:sqs:us-east-1:123456789012:some-other-endpoint",
                                                        Owner = "123456789012",
                                                        Protocol = "sqs",
                                                        SubscriptionArn = "arn:aws:sns:us-east-1:123456789012:some-other-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99",
                                                        TopicArn = "arn:aws:sns:us-east-1:162882392992:mymessage"
                                                    }
                                            }
                    }
                };
                _sns.Expect(s => s.ListSubscriptions(Arg<ListSubscriptionsRequest>.Is.Anything)).Return(response);
                var results = _wrapper.QuerySubscriptions("mymessage").ToArray();

                Assert.AreEqual(2, results.Count());

                Assert.AreEqual("arn:aws:sqs:us-east-1:123456789012:some-endpoint", results[0].Endpoint);
                Assert.AreEqual("123456789012", results[0].Owner);
                Assert.AreEqual("sqs", results[0].Protocol);
                Assert.AreEqual("arn:aws:sns:us-east-1:123456789012:some-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99", results[0].SubscriptionArn);
                Assert.AreEqual("arn:aws:sns:us-east-1:162882392992:mymessage", results[0].TopicArn);

                Assert.AreEqual("arn:aws:sqs:us-east-1:123456789012:some-other-endpoint", results[1].Endpoint);
                Assert.AreEqual("123456789012", results[1].Owner);
                Assert.AreEqual("sqs", results[1].Protocol);
                Assert.AreEqual("arn:aws:sns:us-east-1:123456789012:some-other-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99", results[1].SubscriptionArn);
                Assert.AreEqual("arn:aws:sns:us-east-1:162882392992:mymessage", results[1].TopicArn);

            }

            [Test]
            public void Multiple_Subscriptions_Exists_Matching_This_Name_Only_Sqs_Returned()
            {
                var response = new ListSubscriptionsResponse
                {
                    ListSubscriptionsResult = new ListSubscriptionsResult
                    {
                        Subscriptions = new List<Subscription>
                                            {
                                                new Subscription
                                                    {
                                                        Endpoint = "arn:aws:sqs:us-east-1:123456789012:some-endpoint",
                                                        Owner = "123456789012",
                                                        Protocol = "sqs",
                                                        SubscriptionArn = "arn:aws:sns:us-east-1:123456789012:some-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99",
                                                        TopicArn = "arn:aws:sns:us-east-1:162882392992:some-message"
                                                    },
                                                     new Subscription
                                                    {
                                                        Endpoint = "arn:aws:sqs:us-east-1:123456789012:some-endpoint",
                                                        Owner = "123456789012",
                                                        Protocol = "sqs",
                                                        SubscriptionArn = "arn:aws:sns:us-east-1:123456789012:some-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99",
                                                        TopicArn = "arn:aws:sns:us-east-1:162882392992:mymessage"
                                                    },
                                                     new Subscription
                                                    {
                                                        Endpoint = "arn:aws:sqs:us-east-1:123456789012:some-other-endpoint",
                                                        Owner = "123456789012",
                                                        Protocol = "email",
                                                        SubscriptionArn = "arn:aws:sns:us-east-1:123456789012:some-other-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99",
                                                        TopicArn = "arn:aws:sns:us-east-1:162882392992:mymessage"
                                                    },
                                                     new Subscription
                                                    {
                                                        Endpoint = "arn:aws:sqs:us-east-1:123456789012:yet-other-endpoint",
                                                        Owner = "123456789012",
                                                        Protocol = "sqs",
                                                        SubscriptionArn = "arn:aws:sns:us-east-1:123456789012:yet-other-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99",
                                                        TopicArn = "arn:aws:sns:us-east-1:162882392992:mymessage"
                                                    }
                                            }
                    }
                };

                _sns.Expect(s => s.ListSubscriptions(Arg<ListSubscriptionsRequest>.Is.Anything)).Return(response);
                var results = _wrapper.QuerySubscriptions("mymessage").ToArray();

                Assert.AreEqual(2, results.Count());

                Assert.AreEqual("arn:aws:sqs:us-east-1:123456789012:some-endpoint", results[0].Endpoint);
                Assert.AreEqual("123456789012", results[0].Owner);
                Assert.AreEqual("sqs", results[0].Protocol);
                Assert.AreEqual("arn:aws:sns:us-east-1:123456789012:some-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99", results[0].SubscriptionArn);
                Assert.AreEqual("arn:aws:sns:us-east-1:162882392992:mymessage", results[0].TopicArn);

                Assert.AreEqual("arn:aws:sqs:us-east-1:123456789012:yet-other-endpoint", results[1].Endpoint);
                Assert.AreEqual("123456789012", results[1].Owner);
                Assert.AreEqual("sqs", results[1].Protocol);
                Assert.AreEqual("arn:aws:sns:us-east-1:123456789012:yet-other-subscription:0f56965e-10bf-45b3-a7f4-3872720aed99", results[1].SubscriptionArn);
                Assert.AreEqual("arn:aws:sns:us-east-1:162882392992:mymessage", results[1].TopicArn);

            }
        }
    }
}